package org.geometerplus.android.util;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import org.geometerplus.android.fbreader.RLog;
import org.geometerplus.android.fbreader.library.SQLiteBooksDatabase;
import org.geometerplus.fbreader.Paths;
import org.geometerplus.fbreader.library.Book;
import org.geometerplus.fbreader.library.BooksDatabase;
import org.geometerplus.fbreader.library.FileInfoSet;
import org.geometerplus.fbreader.library.Library;
import org.geometerplus.fbreader.library.SyncImageLoader;
import org.geometerplus.zlibrary.core.filesystem.ZLFile;
import org.geometerplus.zlibrary.core.image.ZLImage;
import org.geometerplus.zlibrary.core.image.ZLLoadableImage;
import org.zixuanstudio.ebook.R;
import org.geometerplus.zlibrary.ui.android.image.ZLAndroidImageData;
import org.geometerplus.zlibrary.ui.android.image.ZLAndroidImageManager;

import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.AssetManager;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Path;
import android.graphics.drawable.Drawable;
import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.MeasureSpec;
import android.widget.TextView;

public class BookUtil {

	private static final String TAG = "BookUtil";
	public static final HashMap<Long, Bitmap> mBookCoverCollection = new HashMap<Long, Bitmap>();

	private static SyncImageLoader mSyncImageLoader;

	private static Context mContext;
	public static mLoadListener mInitListener = null;

	public static boolean isCanUseSdcard() {
		try {
			return Environment.getExternalStorageState().equals(
					Environment.MEDIA_MOUNTED);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}

	public static Bitmap loadImageFromPath(String path) throws IOException {
		ZLFile zlFile = ZLFile.createFileByPath(path);
		ZLImage bookImage = Library.getCover(zlFile);
		if (bookImage instanceof ZLLoadableImage) {
			final ZLLoadableImage loadableImage = (ZLLoadableImage) bookImage;
			if (!loadableImage.isSynchronized()) {
				loadableImage.synchronize();
			}
		}
		final ZLAndroidImageData data = ((ZLAndroidImageManager) ZLAndroidImageManager
				.Instance()).getImageData(bookImage);
		Bitmap cover = data.getBitmap(120, 150);

		return cover;
	}

	public static Bitmap getDefaultBookCover() {
		final Resources resources = mContext.getResources();

		final Bitmap defaultCover = BitmapFactory.decodeResource(resources,
				R.drawable.default_cover);
		return defaultCover;
	}

	public static byte[] getHelperBookCover() {
		RLog.v("BookUtil", "getBookCoverData:");
		final Resources resources = mContext.getResources();
		Bitmap bitmap = BitmapFactory.decodeResource(resources,
				R.drawable.default_cover);
		ByteArrayOutputStream out = null;
		if (bitmap != null) {
			int size = bitmap.getWidth() * bitmap.getHeight() * 4;
			out = new ByteArrayOutputStream(size);
			try {
				bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
				out.close();
			} catch (IOException e) {
				e.printStackTrace();

			}
			bitmap.recycle();
			bitmap = null;
		}
		return (out != null ? out.toByteArray() : null);
	}

	public static byte[] getDefaultCover(Context context) {
		final Resources resources = context.getResources();
		final Bitmap defaultCover = BitmapFactory.decodeResource(resources,
				R.drawable.default_cover);
		ByteArrayOutputStream out = null;
		if (defaultCover != null) {
			int size = defaultCover.getWidth() * defaultCover.getHeight() * 4;
			out = new ByteArrayOutputStream(size);
			try {
				defaultCover.compress(Bitmap.CompressFormat.PNG, 100, out);
				out.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			defaultCover.recycle();
		}
		return (out != null ? out.toByteArray() : null);
	}

	public static Bitmap convertViewToBitmap(View view) {
		RLog.v(TAG, "convertViewToBitmap:" + (view == null));
		view.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
				MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
		view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
		view.buildDrawingCache();
		Bitmap bitmap = view.getDrawingCache();
		return bitmap;
	}

	public static Bitmap getBitmapFromView(View view) {
		view.setDrawingCacheEnabled(true);
		view.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
				MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
		view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
		view.buildDrawingCache();
		Bitmap cacheBitmap = view.getDrawingCache();
		return Bitmap.createBitmap(cacheBitmap);
	}

	public static byte[] getDefaultCover(Context context, String title) {
		View view = LayoutInflater.from(context).inflate(
				R.layout.default_book_cover, null);
		TextView titleView = (TextView) view.findViewById(R.id.book_title);
		titleView.setText(title);
		Bitmap defaultCover = getBitmapFromView(view);
		ByteArrayOutputStream out = null;
		if (defaultCover != null) {
			int size = defaultCover.getWidth() * defaultCover.getHeight() * 4;
			out = new ByteArrayOutputStream(size);
			try {
				defaultCover.compress(Bitmap.CompressFormat.PNG, 100, out);
				out.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			defaultCover.recycle();
		}
		return (out != null ? out.toByteArray() : null);
	}

	public static byte[] getBookCoverData(ZLFile file) {
		Bitmap bitmap = null;
		ZLImage bookImage = Library.getCover(file);
		if (bookImage instanceof ZLLoadableImage) {
			final ZLLoadableImage loadableImage = (ZLLoadableImage) bookImage;
			if (!loadableImage.isSynchronized()) {
				loadableImage.synchronize();
			}
		}
		final ZLAndroidImageData data = ((ZLAndroidImageManager) ZLAndroidImageManager
				.Instance()).getImageData(bookImage);
		bitmap = data.getBitmap(110, 160);
		// bitmap = getCoverBitmap(bookImage);
		if (bitmap == null)
			return null;
		// ByteArrayOutputStream out = null;
		/*
		 * if (bitmap != null) { int size = bitmap.getWidth() *
		 * bitmap.getHeight() * 4; out = new ByteArrayOutputStream(size); try {
		 * bitmap.compress(Bitmap.CompressFormat.PNG, 100, out); out.close(); }
		 * catch (IOException e) { e.printStackTrace(); } bitmap.recycle();
		 * bitmap = null; }
		 */
		//Bitmap bm = resizeBitmap(bitmap);
		return Bitmap2Bytes(bitmap);
	}

	public static byte[] Bitmap2Bytes(Bitmap bm) {
		if (bm == null)
			return null;
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		bm.compress(Bitmap.CompressFormat.PNG, 100, baos);
		return baos.toByteArray();
	}

	/**
	 * 重新设置大小
	 * 
	 * @param bitmap
	 * @return
	 */
	public static final Bitmap resizeBitmap(Bitmap bitmap) {
		return resizeBitmap(bitmap, 106, 151);
	}

	/**
	 * 
	 * @param bitmap
	 * @param maxSize
	 * @return
	 */
	private static final Bitmap resizeBitmap(Bitmap bitmap, int maxwidth,
			int maxheight) {
		int srcWidth = bitmap.getWidth();
		int srcHeight = bitmap.getHeight();
		int width = maxwidth;
		int height = maxheight;
		boolean needsResize = false;
		if (srcWidth > srcHeight) {
			if (srcWidth > maxwidth) {
				needsResize = true;
				height = ((maxheight * srcHeight) / srcWidth);
			}
		} else {
			if (srcHeight > maxheight) {
				needsResize = true;
				width = ((maxwidth * srcWidth) / srcHeight);
			}
		}
		if (needsResize) {
			Bitmap retVal = Bitmap.createScaledBitmap(bitmap, width, height,
					true);
			return retVal;
		} else {
			return bitmap;
		}
	}

	public static void getHelperBook(Context context) {
		AssetManager asset = context.getAssets();
		String books[] = null;
		try {
			books = asset.list("books");

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		for (String book : books) {
			try {
				InputStream is = asset.open("books/" + book);
				writeHelper2Sdcard(is, book);
			} catch (IOException e) {
				e.printStackTrace();
				if (mInitListener != null) {
					mInitListener.onInitError();
				}
			}
		}
		if (mInitListener != null) {
			mInitListener.onInitComplete();
		}

	}

	public interface mLoadListener {
		public void onInit(String Bookpath);

		public void onInitComplete();

		public void onInitError();
	}

	public static void loadDefaultNetStore() {

	}

	private static byte sbuffer[] = new byte[1024];

	public static void writeHelper2Sdcard(InputStream is, String bookName)
			throws IOException {
		FileOutputStream outputStream = null;
		String bookPath = null;
		RLog.v("BookUtil", "Paths.helperBooksPath:" + Paths.helperBooksPath());
		File file = new File(Paths.helperBooksPath());
		if (!file.exists()) {
			if (file.mkdir()) {
				RLog.v("BookUtil", "@@@create directory sucess");
			} else {
				RLog.v("BookUtil", "@@@create directory faile");
			}
		}
		bookPath = Paths.helperBooksPath() + "/" + bookName;
		file = new File(bookPath);
		if (file.exists()) {
			if (mInitListener != null) {
				mInitListener.onInit(bookPath);
			}
			return;
		} else {
			file.createNewFile();
		}
		outputStream = new FileOutputStream(file);
		while (is.read(sbuffer) != -1) {
			outputStream.write(sbuffer);
		}
		if (is != null)
			is.close();
		if (outputStream != null)
			outputStream.close();
		// init book
		if (mInitListener != null) {
			mInitListener.onInit(bookPath);
		}
	}
}
